package com.yunxin.download.server.infra.support.file.export.context;

import com.alibaba.excel.util.IoUtils;
import com.yunxin.common.exception.BusinessException;
import com.yunxin.common.result.ResultCode;
import com.yunxin.download.server.infra.constant.FileExportConstant;
import com.yunxin.download.server.infra.constant.enums.FileTypeEnum;
import com.yunxin.download.server.infra.support.file.FileHeader;
import com.yunxin.download.server.infra.support.file.export.service.CsvFileExportServiceImpl;
import com.yunxin.download.server.infra.support.file.export.service.FileExportService;
import com.yunxin.download.server.infra.support.file.export.service.XlsxFileExportServiceImpl;
import com.yunxin.download.server.infra.utils.AliYunOssUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * @author zero°
 * @since 2023-06-15
 */
@SuppressWarnings({"rawtypes", "unchecked"})
@Slf4j
public class NormalFileExportContext implements FileExportContext {

    private static final String APPEND_ERROR_LOG = "文件追加数据失败";

    /**
     * 当前默认导出为csv
     */
    private FileExportService excelExportService;
    /**
     * 导出文件名称
     */
    private ByteArrayOutputStream outputStream;


    private void initProperty() {
        outputStream = new ByteArrayOutputStream();
    }

    /**
     * @param sheetName        sheetName
     * @param excelHeaderClass excelHeaderClass
     */
    public NormalFileExportContext(String sheetName, Class<? extends FileHeader> excelHeaderClass) {
        initProperty();
        //初始化导出类型
        excelExportService = new XlsxFileExportServiceImpl();
        excelExportService.init(sheetName, excelHeaderClass, outputStream);
    }


    /**
     * 根据模板导出
     *
     * @param fileName    fileName
     * @param inputStream inputStream
     */
    public NormalFileExportContext(String fileName, InputStream inputStream) {
        initProperty();
        //初始化导出类型
        excelExportService = new XlsxFileExportServiceImpl();
        excelExportService.init(fileName, inputStream, outputStream);
    }

    /**
     * @param sheetName         sheetName
     * @param excelHeaderClass  excelHeaderClass
     * @param fileTypeEnum fileTypeEnum
     */
    public NormalFileExportContext(String sheetName, Class<? extends FileHeader> excelHeaderClass, FileTypeEnum fileTypeEnum) {
        initProperty();
        //初始化导出类型
        if (fileTypeEnum == FileTypeEnum.CSV) {
            excelExportService = new CsvFileExportServiceImpl();
        } else {
            excelExportService = new XlsxFileExportServiceImpl();
        }
        excelExportService.init(sheetName, excelHeaderClass, outputStream);
    }


    @Override
    public void appendData(List<Object>  data) {
        try {
            excelExportService.append(data);
        } catch (Exception e) {
            log.error(APPEND_ERROR_LOG, e);
            throw new BusinessException(APPEND_ERROR_LOG, e);
        }
    }


    @Override
    public void appendDataByMap(List<Map<String, Object>> data,Integer isView) {
        try {
            // 数据转换
            List<Map<String, Object>> maps = dataCovert(data,isView);
            excelExportService.appendByMap(maps);
        } catch (Exception e) {
            log.error(APPEND_ERROR_LOG, e);
            throw new BusinessException(ResultCode.SYSTEM_EXECUTION_ERROR);
        }
    }


    /**
     * 导出到oss
     */
    @Override
    public String export2Oss(String fileTypeSuffix, String userName, String fileName) {
        //释放资源
        excelExportService.finish();
        byte[] byteArray = this.outputStream.toByteArray();
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray)){
            //生成随机osskey
            String ossKey = FileExportConstant.OSS_FILE_FOLDER + userName + "/" + userName + "-" + fileName + fileTypeSuffix;
            AliYunOssUtil.X.upload(ossKey, byteArrayInputStream);
            return ossKey;
        } catch (Exception ex) {
            throw new BusinessException(ResultCode.SYSTEM_EXECUTION_ERROR);
        } finally {
            this.close();
        }
    }

    /**
     * 导出到本地
     *
     */
    @Override
    public void export2Local(String filename, String fileTypeSuffix, String url) {
        File file = new File(url, filename + fileTypeSuffix);
        try (FileOutputStream in = new FileOutputStream(file)) {
            //释放资源
            excelExportService.finish();
            byte[] byteArray = this.outputStream.toByteArray();
            in.write(byteArray, 0, byteArray.length);
        } catch (Exception ex) {
            throw new BusinessException(ResultCode.SYSTEM_EXECUTION_ERROR);
        }
    }

    /**
     * oss文件下载
     *
     * @param ossFileKey   oss文件Key
     */
    @Override
    public void downloadOssExportFile(String ossFileKey, OutputStream outputStream) {
        try {
            IoUtils.copy(AliYunOssUtil.X.download(ossFileKey), outputStream);
        } catch (Exception e) {
            log.error("文件下载失败", e);
        }
    }

    /**
     * 释放资源
     */
    @Override
    public void close() {
        try {
            if (this.outputStream != null) {
                this.outputStream.close();
            }
        } catch (Exception e) {
            log.error("资源释放异常", e);
        }
    }

    private List<Map<String, Object>> dataCovert(List<Map<String, Object>> data,Integer isView){
        data.forEach(x->{
            Object seedQuota = x.get("sesameSeedQuota");
            Object merchantType  = x.get("merchantType");
            var responsiblePersonPhone  = x.get("responsiblePersonPhone");
            var userPhone = x.get("userPhone");
            if(isView==1){
                if(responsiblePersonPhone!=null){
                    String str = responsiblePersonPhone.toString();
                    String targetPhone = str.substring(0, 3) + "****" + str.substring(7);
                    x.put("responsiblePersonPhone",targetPhone);
                }
                if(userPhone!=null){
                    String phone = userPhone.toString();
                    String targetUserPhone = phone.substring(0, 3) + "****" + phone.substring(7);
                    x.put("userPhone",targetUserPhone);
                }

            }
            if(seedQuota!=null){
                if(seedQuota.equals(1)){
                    x.put("sesameSeedQuota","<600");
                }else if(seedQuota.equals(2)){
                    x.put("sesameSeedQuota","600-650");
                }
                else if(seedQuota.equals(3)){
                    x.put("sesameSeedQuota","651-700");
                }
                else if(seedQuota.equals(4)){
                    x.put("sesameSeedQuota",">700");
                }
            }
           if(merchantType!=null){
               if(merchantType.equals(1)){
                   x.put("merchantType","个人");
               }else {
                   x.put("merchantType","企业");
               }
           }

        });

        return data;
    }






    /**
     * 获取导出文件类型
     *
     * @return String
     */
    @Override
    public String getFileTypeSuffix() {
        return excelExportService.getFileTypeSuffix();
    }
}
